//
//  LMHotFixManager.m
//  LMHotFixKit
//
//  Created by mengmenglu on 6/24/16.
//  Copyright © 2016 Hangzhou TaiXuan Network Technology Co., Ltd. All rights reserved.
//

#import "LMHotFixManager.h"

#import  "LMHotFixHeaderKit.h"
#import "AFNetworking.h"
#import "ZipArchive.h"
#import "JPEngine.h"


static NSString *_patchPlistURL = nil;
static NSString *_patchZipURL = nil;
static NSDictionary *patchVersionInfo = nil;

@implementation LMHotFixManager


#pragma mark - Private
+ (NSString *)patchPlistURL {
    
    if (!_patchPlistURL) {
        _patchPlistURL = [NSString stringWithFormat:@"%@", APP_VRSION_PLIST_URL];
    }
    return _patchPlistURL;
}


+ (NSString *)patchZipURL {
    
    if (!_patchZipURL) {
        _patchZipURL = [NSString stringWithFormat:@"%@", APP_PATCH_URL];
    }
    return _patchZipURL;
}


#pragma mark - Class Methods
#pragma mark 判断本地调试功能是否已开启
+ (BOOL)localDebugEnable {
    NSString *localPatchPath = [NSString stringWithFormat:@"%@/Patch", [[NSBundle mainBundle] bundlePath]];
    return [[NSFileManager defaultManager] fileExistsAtPath:localPatchPath];
}



#pragma mark 启动Wax
+ (void)start {
    [JPEngine startEngine];
}


#pragma mark 执行js语句
+ (void)runJavaScriptString:(NSString *)javaScriptString {
    [JPEngine evaluateScript:javaScriptString];
}


#pragma mark 加载远程js库文件
+ (void)runRemoteJavaScriptFile:(NSString *)javaScriptFileName {
    
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *unzipPath = [documentDirectory stringByAppendingPathComponent:@"patch"];
    NSString *javaScriptFilePath = [unzipPath stringByAppendingFormat:@"/%@", javaScriptFileName];
    //NSLog(@"%@", javaScriptFilePath);
    if ([[NSFileManager defaultManager] fileExistsAtPath:javaScriptFilePath]) {
        [JPEngine evaluateScriptWithPath:javaScriptFilePath];
        NSLog(@"运行远程服务器 %@ 文件成功", javaScriptFileName);
    } else {
        NSLog(@"远程服务器 %@ 文件不存在", javaScriptFileName);
    }
}


#pragma mark 加载本地js库文件
+ (void)runLocalJavaScriptFile:(NSString *)localJavaScriptFileName {
    
    NSString *localPatchPath = [NSString stringWithFormat:@"%@/Patch", [[NSBundle mainBundle] bundlePath]];
    NSString *javaScriptFilePath = [localPatchPath stringByAppendingFormat:@"/%@", localJavaScriptFileName];
    //NSLog(@"%@", javaScriptFilePath);
    if ([[NSFileManager defaultManager] fileExistsAtPath:javaScriptFilePath]) {
        [JPEngine evaluateScriptWithPath:javaScriptFilePath];
        NSLog(@"运行本地 %@ 成功", localJavaScriptFileName);
    } else {
        NSLog(@"%@ 本地文件不存在", localJavaScriptFileName);
    }
}


#pragma mark 更新版本控制plist文件
+ (void)updateVersionPlistFile {
    
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        patchVersionInfo = [[NSDictionary alloc] initWithContentsOfURL:[NSURL URLWithString:[self patchPlistURL]]];
        NSLog(@"versionInfo = %@", patchVersionInfo);
        if ([patchVersionInfo count] > 0) {
            NSString *key = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
            NSString *patchVersion = [patchVersionInfo objectForKey:key];
            if ([patchVersion length] > 0) {
                
                NSString *patchVersionCache = [self patchVersionCache];
                if ([patchVersionCache isEqualToString:patchVersion]) {
                    NSLog(@"版本相同，无需更新补丁文件");
                }
                else {
                    NSLog(@"有版本信息，需更新补丁文件");
                    [self updatePatchFiles];
                }
            }
            else {
                NSLog(@"无版本信息，清除补丁缓存");
                [self cleanPatchCache];
            }
        }
        else {
            NSLog(@"清除补丁缓存");
            [self cleanPatchCache];
        }
    });
}



#pragma mark 更新补丁文件
+ (void)updatePatchFiles {
    
    [LMHotFixManager cleanPatchCache];
    
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    NSURL *URL = [NSURL URLWithString:[self patchZipURL]];
    NSLog(@"补丁下载地址: %@", [URL absoluteString]);
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        
        NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *zipPath = [documentDirectory stringByAppendingPathComponent:@"patch.zip"];
        NSString *unzipPath = [documentDirectory stringByAppendingPathComponent:@"patch"];
        
        if (error) {
            NSLog(@"补丁下载失败 %@", error);
        }
        else {
            NSLog(@"文件下载成功: %@", [filePath absoluteString]);
            // 解压文件
            BOOL success = [SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath];
            if (success) {
                NSLog(@"补丁解压成功");
                [self updatePatchVersionCache];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self runRemoteJavaScriptFile:@"patch.js"];
                });
            }
        }
    }];
    
    [downloadTask resume];
}



#pragma mark 更新补丁文件，并提供更新成功后的回调功能
+ (void)updatePatchFiles:(UpdatePatchFilesSuccessBlock)updatePatchFilesSuccessBlock {
    
    [LMHotFixManager cleanPatchCache];
    
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    NSURL *URL = [NSURL URLWithString:[self patchZipURL]];
    NSLog(@"补丁下载地址: %@", [URL absoluteString]);
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        
        NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *zipPath = [documentDirectory stringByAppendingPathComponent:@"patch.zip"];
        NSString *unzipPath = [documentDirectory stringByAppendingPathComponent:@"patch"];
        
        if (error) {
            NSLog(@"补丁下载失败 %@", error);
        } else {
            NSLog(@"文件下载成功: %@", [filePath absoluteString]);
            // 解压文件
            BOOL success = [SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath];
            if (success) {
                NSLog(@"补丁解压成功");
                [self updatePatchVersionCache];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self runRemoteJavaScriptFile:@"patch.js"];
                });
            }
        }
        updatePatchFilesSuccessBlock();
        
    }];
    
    [downloadTask resume];
}


#pragma mark 清除补丁缓存
+ (void)cleanPatchCache {
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *zipPath = [documentDirectory stringByAppendingPathComponent:@"patch.zip"];
    NSString *unzipPath = [documentDirectory stringByAppendingPathComponent:@"patch"];
    [[NSFileManager defaultManager] removeItemAtPath:zipPath error:nil];
    [[NSFileManager defaultManager] removeItemAtPath:unzipPath error:nil];
}


#pragma mark 更新缓存补丁版本号
+ (void)updatePatchVersionCache {
    
    if ([patchVersionInfo count] > 0) {
        
        NSString *key = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
        NSString *patchVersion = [patchVersionInfo objectForKey:key];
        if ([patchVersion length] > 0) {
            
            NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
            NSString *key = [NSString stringWithFormat:@"app_patch_version_%@", currentVersion];
            NSLog(@"更新 %@ 缓存信息 %@", key, patchVersion);
            [[NSUserDefaults standardUserDefaults] setValue:patchVersion forKey:key];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }
    }
}


#pragma mark 获取缓存的补丁版本号
+ (NSString *)patchVersionCache {
    
    NSString *currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString *)kCFBundleVersionKey];
    NSString *key = [NSString stringWithFormat:@"app_patch_version_%@", currentVersion];
    NSLog(@"获取 %@ 缓存信息 %@", key, [[NSUserDefaults standardUserDefaults] valueForKey:key]);
    return [[NSUserDefaults standardUserDefaults] valueForKey:key];
}


@end
